# 5. eye_player.py
import os
import time
import random
import numpy as np
import rlottie_python as rlottie
from PIL import Image
import sdl2
from text_render import pil_image_to_texture

# 眉毛渲染的帧序列 24-34 是眨眼的动画效果
class EyesCachePlayer:
    def __init__(self, json_path, renderer):
        self.animation = rlottie.LottieAnimation.from_file(os.path.abspath(json_path))
        self.width, self.height = self.animation.lottie_animation_get_size()
        self.cached_frames = {}
        self.sequence = [24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
        self.frame_durations = [30, 30, 40, 50, 60, 70, 80, 90, 100, 120] #动态眨眼效果
        self.state = 'idle' #状态机，眨眼
        self.current_index = 0
        self.last_blink_time = time.time()
        self.blink_interval = self.get_random_interval()
        self.frame_interval = 0.05 #每个0.05秒播放一帧
        self.last_frame_time = time.time() * 1000  # 统一改成毫秒
        self.renderer = renderer
        self.preload_frames()

    def preload_frames(self):
        for frame in self.sequence:
            frame_bytes = self.animation.lottie_animation_render(
                frame_num=frame, width=self.width, height=self.height)
            rgba_frame = np.frombuffer(frame_bytes, dtype=np.uint8).reshape((self.height, self.width, 4))
            rgba_frame = rgba_frame[..., [2, 1, 0, 3]]
            pil_image = Image.fromarray(rgba_frame, mode="RGBA")
            texture = pil_image_to_texture(pil_image, self.renderer)
            self.cached_frames[frame] = texture
        print(f"[INFO] 预缓存了{len(self.cached_frames)}帧眉毛动画")
    
    def get_random_interval(self):
        return random.uniform(4.0, 6.0)
    
    def render(self):
        now = time.time() * 1000  # 统一单位：ms

        if self.state == 'idle':
            if now - self.last_blink_time >= self.blink_interval * 1000:
                self.state = 'blinking'
                self.current_index = 0
                self.last_frame_time = now
            else:
                texture = self.cached_frames.get(self.sequence[0])
                if texture:
                    sdl2.SDL_RenderCopy(self.renderer, texture, None, None)
                return

        if self.state == 'blinking':
            if self.current_index >= len(self.sequence) or self.current_index >= len(self.frame_durations):
                # 防御式退出，防止越界
                self.state = 'idle'
                self.last_blink_time = now
                self.blink_interval = self.get_random_interval()
                return

            if now - self.last_frame_time >= self.frame_durations[self.current_index]:
                self.last_frame_time = now
                frame_id = self.sequence[self.current_index]
                texture = self.cached_frames.get(frame_id)
                if texture:
                    sdl2.SDL_RenderCopy(self.renderer, texture, None, None)
                self.current_index += 1
            else:
                frame_id = self.sequence[self.current_index]
                texture = self.cached_frames.get(frame_id)
                if texture:
                    sdl2.SDL_RenderCopy(self.renderer, texture, None, None)
                    
# ========= 默认嘴型的预渲染，建议默认嘴型和眨眼做成一份文件 ===========
class StaticMouthCache:
    def __init__(self, mouth_player, renderer):
        self.texture = self.pre_render(mouth_player, renderer)

    def pre_render(self, player, renderer):
        player.set_play_segment(0, 0)
        image = player.render_next_frame()
        return pil_image_to_texture(image, renderer)

    def render(self, renderer):
        sdl2.SDL_RenderCopy(renderer, self.texture, None, None)